package com.sojson.socket;

import java.util.List;
import java.util.Map;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.sojson.util.socket.SocketPoolUtil;
import com.sojson.util.socket.WebSocketInterface;

import lombok.extern.slf4j.Slf4j;

/**
 * WebSocket控制器
 * 
 * @author liu
 * @date 2021-04-04
 */
@Slf4j
@Component
@ServerEndpoint("/skt")
public class WebSocket implements WebSocketInterface {

    /***/
    private static final long serialVersionUID = -6515199827869750860L;

    /** Session */
    private Session sess;
    /** 缓存中的Key */
    private String cachekey;

    /**
     * 建立连接的注解,前端触发上面URI时会进入此注解标注的方法,和之前关于DWR文章中的onpage方法类似
     * 
     * @param sess  Session
     * @param token 路径参数
     * @throws Exception 
     */
    @OnOpen
    @Override
    public void onOpen(Session sess) throws Exception {
        // 验证Token
        System.out.println(1);
        Map<String, List<String>> requestParameterMap = sess.getRequestParameterMap();
        System.out.println(requestParameterMap);
        System.out.println(sess.getPathParameters());

        // 设置缓存中的Key
        setCachekey("1");
        // 设置Session
        setSess(sess);
        System.out.println("token: " + "1");

        // 添加到连接池
        SocketPoolUtil.put(cachekey, this);
        log.info(new StringBuilder().append("====== onOpen: ").append("1").append(" ======").toString());
    }

    /**
     * 关闭连接,销毁Session的时候触发的方法
     * 
     * @param token 路径参数
     */
    @OnClose
    @Override
    public void onClose() {
        // 从连接池中删除
        SocketPoolUtil.remove(cachekey);
        log.info(new StringBuilder().append("====== onClose: ").append("1").append(" ======").toString());
    }

    /**
     * 收到前端传来的消息后执行的方法
     * 
     * @param sess  Session
     * @param msg   前端传过来的消息
     * @throws Exception 
     */
    @OnMessage
    @Override
    public void onMsg(Session sess, String msg) throws Exception {
        // 从连接池获取服务端到客户端的通道
        WebSocketInterface webSocket = SocketPoolUtil.get(cachekey);
        log.info("收到来自: " + sess.getId() + "的消息," + msg);

        // 通知收到
        webSocket.sendMsg(1, "", "", "");
    }

    /**
     * 发生错误时触发的方法
     * 
     * @param sess  Session
     * @param err   异常
     */
    @OnError
    @Override
    public void onError(Session sess, Throwable err) {
        err.printStackTrace();
        log.info(new StringBuilder("连接发生错误: ").append(sess.getId()).append(",").append(err.getMessage()).toString());
    }

    @Override
    public synchronized void sendMsg(int status, String message, Object datas, String types) {

        JSONObject result = new JSONObject();
        result.put("status", status);
        result.put("types", types);
        result.put("message", message);
        result.put("data", datas);
        if (this.sess.isOpen()) {
            this.sess.getAsyncRemote().sendText(result.toJSONString());
            log.info("sendMsg: status=" + status + ",message=" + message + ",types=" + types + ",datas=" + datas);
        }
    }

    /**
     * 获取缓存中的Key
     * 
     * @return
     */
    public String getCachekey() {
        return cachekey;
    }

    /**
     * 设置缓存中的Key
     * 
     * @param cachekey
     */
    public void setCachekey(String cachekey) {
        this.cachekey = cachekey;
    }

    /**
     * 获取Session
     * 
     * @return
     */
    public Session getSess() {
        return sess;
    }

    /**
     * 设置Session
     * 
     * @param sess
     */
    public void setSess(Session sess) {
        this.sess = sess;
    }

}